home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / GIF.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-05  |  8.5 KB  |  388 lines

  1. /****************************************************************************
  2. *                   gif.c
  3. *
  4. *  Gif-format file reader.
  5. *
  6. *  NOTE:  Portions of this module were written by Steve Bennett and are used
  7. *         here with his permission.
  8. *
  9. *  from Persistence of Vision(tm) Ray Tracer
  10. *  Copyright 1996 Persistence of Vision Team
  11. *---------------------------------------------------------------------------
  12. *  NOTICE: This source code file is provided so that users may experiment
  13. *  with enhancements to POV-Ray and to port the software to platforms other 
  14. *  than those supported by the POV-Ray Team.  There are strict rules under
  15. *  which you are permitted to use this file.  The rules are in the file
  16. *  named POVLEGAL.DOC which should be distributed with this file. If 
  17. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  18. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  19. *  Forum.  The latest version of POV-Ray may be found there as well.
  20. *
  21. * This program is based on the popular DKB raytracer version 2.12.
  22. * DKBTrace was originally written by David K. Buck.
  23. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  24. *
  25. *****************************************************************************/
  26.  
  27. /*
  28.  * The following routines were borrowed freely from FRACTINT, and represent
  29.  * a generalized GIF file decoder.  This once seemed the best, most universal
  30.  * format for reading in Bitmapped images, until Unisys began enforcing
  31.  * its patent on the LZ compression that GIF uses.  POV-Ray, as freeware, is
  32.  * exempt from GIF licensing fees.  GIF is a Copyright of Compuserve, Inc.
  33.  *
  34.  * Swiped and converted to entirely "C" coded routines by AAC for the most
  35.  * in future portability!
  36.  */
  37.  
  38. #include "frame.h"
  39. #include "povproto.h"
  40. #include "gif.h"
  41. #include "gifdecod.h"
  42. #include "povray.h"
  43.  
  44.  
  45.  
  46. /*****************************************************************************
  47. * Local preprocessor defines
  48. ******************************************************************************/
  49.  
  50.  
  51.  
  52. /*****************************************************************************
  53. * Local typedefs
  54. ******************************************************************************/
  55.  
  56.  
  57.  
  58. /*****************************************************************************
  59. * Local variables
  60. ******************************************************************************/
  61.  
  62. static IMAGE *Current_Image;
  63. static int Bitmap_Line;
  64. static FILE *Bit_File;
  65. unsigned char *decoderline  /*  [2049] */ ;  /* write-line routines use this */
  66.  
  67. static IMAGE_COLOUR *gif_colour_map;
  68. static int colourmap_size;
  69.  
  70.  
  71.  
  72. /*****************************************************************************
  73. * Static functions
  74. ******************************************************************************/
  75.  
  76.  
  77.  
  78. /*****************************************************************************
  79. *
  80. * FUNCTION
  81. *
  82. *   out_line
  83. *
  84. * INPUT
  85. *   
  86. * OUTPUT
  87. *   
  88. * RETURNS
  89. *   
  90. * AUTHOR
  91. *
  92. *   POV-Ray Team
  93. *   
  94. * DESCRIPTION
  95. *
  96. *   -
  97. *
  98. * CHANGES
  99. *
  100. *   -
  101. *
  102. ******************************************************************************/
  103.  
  104. int out_line (pixels, linelen)
  105. unsigned char *pixels;
  106. int linelen;
  107. {
  108.   register int x;
  109.   register unsigned char *line;
  110.  
  111.   if (Bitmap_Line == Current_Image->iheight)
  112.   {
  113.     Warning (0.0, "Extra data at end of GIF image.\n");
  114.     return (0) ;
  115.   }
  116.  
  117.   line = Current_Image->data.map_lines[Bitmap_Line++];
  118.  
  119.   for (x = 0; x < linelen; x++)
  120.   {
  121.     if ((int)(*pixels) > Current_Image->Colour_Map_Size)
  122.     {
  123.       Error ("Error - GIF image map color out of range.\n");
  124.     }
  125.  
  126.     line[x] = *pixels;
  127.  
  128.     pixels++;
  129.   }
  130.  
  131.   return (0);
  132. }
  133.  
  134.  
  135.  
  136.  
  137. /*****************************************************************************
  138. *
  139. * FUNCTION
  140. *
  141. *   gif_get_byte
  142. *
  143. * INPUT
  144. *   
  145. * OUTPUT
  146. *   
  147. * RETURNS
  148. *   
  149. * AUTHOR
  150. *
  151. *   POV-Ray Team
  152. *   
  153. * DESCRIPTION
  154. *
  155. *   Get byte from file, return the next byte or an error.
  156. *
  157. * CHANGES
  158. *
  159. *   -
  160. *
  161. ******************************************************************************/
  162.  
  163. int gif_get_byte()
  164. {
  165.   register int byte;
  166.  
  167.   if ((byte = getc(Bit_File)) != EOF)
  168.   {
  169.     return (byte);
  170.   }
  171.   else
  172.   {
  173.     Error ("Error reading data from GIF image.\n");
  174.   }
  175.  
  176.   /* Keep the compiler happy. */
  177.  
  178.   return(0);
  179. }
  180.  
  181.  
  182.  
  183. /*****************************************************************************
  184. *
  185. * FUNCTION
  186. *
  187. *   Read_Gif_Image
  188. *
  189. * INPUT
  190. *   
  191. * OUTPUT
  192. *   
  193. * RETURNS
  194. *   
  195. * AUTHOR
  196. *
  197. *   POV-Ray Team
  198. *   
  199. * DESCRIPTION
  200. *
  201. *   Main GIF file decoder.
  202. *
  203. * CHANGES
  204. *
  205. *   -
  206. *
  207. ******************************************************************************/
  208.  
  209. void Read_Gif_Image(Image, filename)
  210. IMAGE *Image;
  211. char *filename;
  212. {
  213.   register int i, j, status;
  214.   unsigned finished, planes;
  215.   unsigned char buffer[16];
  216.  
  217.   status = 0;
  218.  
  219.   Current_Image = Image;
  220.  
  221.   if ((Bit_File = Locate_File(filename, READ_FILE_STRING, ".gif", ".GIF",TRUE)) == NULL)
  222.   {
  223.     Error ("Error opening GIF image.\n");
  224.   }
  225.  
  226.   /* Get the screen description. */
  227.  
  228.   for (i = 0; i < 13; i++)
  229.   {
  230.     buffer[i] = (unsigned char)gif_get_byte();
  231.   }
  232.  
  233.   /* Use updated GIF specs. */
  234.  
  235.   if (strncmp((char *) buffer,"GIF",3) == 0)  /* Allow only GIF87 and GIF89 */
  236.   {
  237.     if ((buffer[3] != '8') || ((buffer[4] != '7') && (buffer[4]) != '9') ||
  238.         (buffer[5] < 'A') || (buffer[5]) > 'z')
  239.     {
  240.       Error ("Unsupported GIF version %c%c%c.\n",
  241.              buffer[3], buffer[4], buffer[5]);
  242.     }
  243.   }
  244.   else
  245.   {
  246.     Error ("File is not in GIF format.\n");
  247.   }
  248.  
  249.   planes = ((unsigned)buffer[10] & 0x0F) + 1;
  250.  
  251.   colourmap_size = (int)(1 << planes);
  252.  
  253.   gif_colour_map = (IMAGE_COLOUR *)POV_CALLOC((size_t)colourmap_size, sizeof(IMAGE_COLOUR), "GIF color map");
  254.  
  255.   /* Color map (better be!) */
  256.  
  257.   if ((buffer[10] & 0x80) == 0)
  258.   {
  259.     Error ("Error in GIF color map.\n");
  260.   }
  261.  
  262.   for (i = 0; i < colourmap_size ; i++)
  263.   {
  264.     gif_colour_map[i].Red    = (unsigned char)gif_get_byte();
  265.     gif_colour_map[i].Green  = (unsigned char)gif_get_byte();
  266.     gif_colour_map[i].Blue   = (unsigned char)gif_get_byte();
  267.     gif_colour_map[i].Filter = 0;
  268.     gif_colour_map[i].Transmit = 0;
  269.   }
  270.  
  271.   /* Now display one or more GIF objects. */
  272.  
  273.   finished = FALSE;
  274.  
  275.   while (!finished)
  276.   {
  277.     switch (gif_get_byte())
  278.     {
  279.       /* End of the GIF dataset. */
  280.  
  281.       case ';':
  282.  
  283.         finished = TRUE;
  284.         status = 0;
  285.  
  286.         break;
  287.  
  288.       /* GIF Extension Block. */
  289.  
  290.       case '!':
  291.  
  292.         /* Read (and ignore) the ID. */
  293.  
  294.         gif_get_byte();
  295.  
  296.         /* Get data len. */
  297.  
  298.         while ((i = gif_get_byte()) > 0)
  299.         {
  300.           for (j = 0; j < i; j++)
  301.           {
  302.             /* Flush data. */
  303.  
  304.             gif_get_byte();
  305.           }
  306.         }
  307.  
  308.         break;
  309.  
  310.       /* Start of image object. Get description. */
  311.  
  312.       case ',':
  313.  
  314.         for (i = 0; i < 9; i++)
  315.         {
  316.           /* EOF test (?).*/
  317.  
  318.           if ((j = gif_get_byte()) < 0)
  319.           {
  320.             status = -1;
  321.  
  322.             break;
  323.           }
  324.  
  325.           buffer[i] = (unsigned char) j;
  326.         }
  327.  
  328.         /* Check "interlaced" bit. */
  329.  
  330.         if (j & 0x40)
  331.         {
  332.           Error ("Interlacing in GIF image unsupported.\n");
  333.         }
  334.  
  335.         if (status < 0)
  336.         {
  337.           finished = TRUE;
  338.  
  339.           break;
  340.         }
  341.  
  342.         Image->iwidth  = buffer[4] | (buffer[5] << 8);
  343.         Image->iheight = buffer[6] | (buffer[7] << 8);
  344.  
  345.         Image->width = (DBL) Image->iwidth;
  346.         Image->height = (DBL) Image->iheight;
  347.  
  348.         Bitmap_Line = 0;
  349.  
  350.         Image->Colour_Map_Size = colourmap_size;
  351.         Image->Colour_Map = gif_colour_map;
  352.  
  353.         Image->data.map_lines = (unsigned char **)POV_MALLOC(Image->iheight * sizeof(unsigned char *), "GIF image");
  354.  
  355.         for (i = 0 ; i < Image->iheight ; i++)
  356.         {
  357.           Image->data.map_lines[i] = (unsigned char *)POV_CALLOC((size_t)Image->iwidth, sizeof(unsigned char), "GIF image line");
  358.         }
  359.  
  360.         /* Setup the color palette for the image. */
  361.  
  362.         decoderline = (unsigned char *)POV_CALLOC(Image->iwidth, sizeof(unsigned char), "GIF decoder line");
  363.  
  364.         /* Put bytes in Buf. */
  365.  
  366.         status = decoder(Image->iwidth);
  367.  
  368.         POV_FREE (decoderline);
  369.  
  370.         decoderline = NULL;
  371.  
  372.         finished = TRUE;
  373.  
  374.         break;
  375.  
  376.       default:
  377.  
  378.         status = -1;
  379.  
  380.         finished = TRUE;
  381.  
  382.         break;
  383.     }
  384.   }
  385.  
  386.   fclose(Bit_File);
  387. }
  388.